'use strict';

const kitx = require('kitx');

const accessKeyId = 'LTAIrhFxeiNFnGTm';
const secretAccessKey = 'U2nQcilv5jodw9SsMOviy2KCSjszsh';
const DYSMSAPI_ENDPOINT = 'https://dysmsapi.aliyuncs.com';

function request(action, params = {}, opts = {}) {
    const endpoint = DYSMSAPI_ENDPOINT;

    // 1. compose params
    // format action until formatAction is false
    if (opts.formatAction !== false) {
        action = firstLetterUpper(action);
    }

    // format params until formatParams is false
    if (opts.formatParams !== false) {
        params = formatParams(params);
    }
    const defaults = buildParams();

    params = Object.assign({ Action: action }, defaults, params);

    // 2. caculate signature
    const method = (opts.method || 'GET').toUpperCase();
    const normalized = normalize(params);
    const canonicalized = canonicalize(normalized);
    // 2.1 get string to sign
    const stringToSign = `${method}&${encode('/')}&${encode(canonicalized)}`;
    // 2.2 get signature
    const key = secretAccessKey + '&';
    const signature = kitx.sha1(stringToSign, key, 'base64');
    // add signature
    normalized.push(['Signature', encode(signature)]);
    // 3. generate final url
    const url = `${endpoint}/?${canonicalize(normalized)}`;
    console.log('===url===', url);
    // 4. send request
}

function firstLetterUpper(str) {
    return str.slice(0, 1).toUpperCase() + str.slice(1);
}

function formatParams(params) {
    const keys = Object.keys(params);
    const newParams = {};
    const len = keys.length;
    for (let i = 0; i < len; i++) {
        const key = keys[i];
        newParams[firstLetterUpper(key)] = params[key];
    }
    return newParams;
}

function timestamp() {
    const date = new Date();
    const YYYY = date.getUTCFullYear();
    const MM = kitx.pad2(date.getUTCMonth() + 1);
    const DD = kitx.pad2(date.getUTCDate());
    const HH = kitx.pad2(date.getUTCHours());
    const mm = kitx.pad2(date.getUTCMinutes());
    const ss = kitx.pad2(date.getUTCSeconds());
    // 删除掉毫秒部分
    return `${YYYY}-${MM}-${DD}T${HH}:${mm}:${ss}Z`;
}

function buildParams() {
    return {
        Format: 'JSON',
        SignatureMethod: 'HMAC-SHA1',
        SignatureNonce: kitx.makeNonce(),
        SignatureVersion: '1.0',
        Timestamp: timestamp(),
        AccessKeyId: accessKeyId,
        Version: '2017-05-25',
    };
}

function normalize(params) {
    const list = [];
    const keys = Object.keys(params).sort();
    const len = keys.length;
    for (let i = 0; i < len; i++) {
        const key = keys[i];
        const value = params[key];
        if (Array.isArray(value)) {
            repeatList(list, key, value);
        } else {
            list.push([encode(key), encode(value)]); //push []
        }
    }
    return list;
}

function encode(str) {
    const result = encodeURIComponent(str);
    return result.replace(/\!/g, '%21')
        .replace(/\'/g, '%27')
        .replace(/\(/g, '%28')
        .replace(/\)/g, '%29')
        .replace(/\*/g, '%2A');
}

function canonicalize(normalized) {
    const fields = [];
    const len = normalized.length;
    for (let i = 0; i < len; i++) {
        const [key, value] = normalized[i];
        fields.push(key + '=' + value);
    }
    return fields.join('&');
}

//  SMS_60460023    注册
//  SMS_49375019    找回密码

request('SendSms', {
    PhoneNumbers: '13067856109',
    SignName: '阿里云短信测试专用',
    TemplateCode: 'SMS_123140076',
    TemplateParam: '{"customer":"chun"}',
});